﻿using Autodesk.AutoCAD.DatabaseServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace AutoCadConvert
{
    public class Mesa:BspObject
    {
        public class Data
        {
            public int type;
            public List<Point> m_points;
        }
        public ObjectId id;//标记
        public string Name;
        public List<Data> m_PointLst = new List<Data>();
        public double FloorHeight=700;//离地高度
        public double MesaThickness=50;//台面自身的厚度信息
        public bool AutoDoor = true;
        public IEnumerable<XElement> PointNode(List<Point> lstPt)
        {
            int idx = 0;
            foreach (Point pt in lstPt)
            {
                yield return new XElement("_" + idx++, pt.ToMirror().To3DString());
            }
        }
        public IEnumerable<XElement> TypeNode(int type)
        {
            if (m_PointLst != null)
            {
                int idx = 0;
                foreach (Data data in m_PointLst)
                {
                    if(data.type==type)
                        yield return new XElement("_" + idx++, PointNode(data.m_points));
                }
            }
        }
        public override IEnumerable<XElement> ToXml()
        {
            if (FloorHeight > BspObject.dWallHeight/2)
                AutoDoor = false;
            return base.ToXml().Concat(new XElement[] {
                new XElement("Name",Name),
                new XElement("Add",TypeNode(1)),
                new XElement("Sub",TypeNode(2)),
                new XElement("FloorHeight",FloorHeight*Unit),
                new XElement("MesaThickness",MesaThickness*Unit),
                new XElement("AutoDoor",AutoDoor?1:0),
            });
        }
    }
    public class MesaNode:Collection
    {
        List<Mesa> m_MesaNode = new List<Mesa>();
        public MesaNode(House house):base(house)
        {
        }
        public override void AddData(Entity value)
        {
            //添加点数据
            base.AddData(value);
            Mesa mesa = new Mesa();
            if (value is Autodesk.AutoCAD.DatabaseServices.Line)
            {
                throw new Exception("错误：造型不是闭合的多段线");
            }
            else if (value is Autodesk.AutoCAD.DatabaseServices.Polyline)
            {
                List<Point> points = new List<Point>();
                Autodesk.AutoCAD.DatabaseServices.Polyline entity = value as Autodesk.AutoCAD.DatabaseServices.Polyline;
                if(entity.Elevation==0 || entity.Thickness==0)
                    throw new Exception("造型图层，多段线未设置标高和厚度，请在特性窗口设置");
                mesa.id = entity.ObjectId;
                mesa.FloorHeight = entity.Elevation;
                mesa.MesaThickness = entity.Thickness;
                for (int i = 0; i < entity.NumberOfVertices; i++)
                {
                    if (SegmentType.Line == entity.GetSegmentType(i))
                    {
                        Point ptSt = new Point(entity.GetLineSegmentAt(i).StartPoint);
                        Point ptEnd = new Point(entity.GetLineSegmentAt(i).EndPoint);
                        if (points.Count == 0)
                            points.Add(ptSt);
                        else if (points.Last() != ptSt)
                            points.Add(ptSt);

                        if (points.Last() != ptEnd)
                            points.Add(ptEnd);
                    }
                    else if(SegmentType.Arc == entity.GetSegmentType(i))
                    {
                        points.Add(new Point(){X = entity.GetPointAtDist(entity.Length / 4).X,Y = entity.GetPointAtDist(entity.Length / 4).Y,Z = entity.GetPointAtDist(entity.Length / 4).Z});
                        points.Add(new Point(){X = entity.GetPointAtDist(entity.Length / 4 * 2).X,Y = entity.GetPointAtDist(entity.Length / 4 * 2).Y,Z = entity.GetPointAtDist(entity.Length / 4 * 2).Z});
                        points.Add(new Point(){X = entity.GetPointAtDist(entity.Length / 4 * 3).X,Y = entity.GetPointAtDist(entity.Length / 4 * 3).Y,Z = entity.GetPointAtDist(entity.Length / 4 * 3).Z});
                    }
                }
                mesa.m_PointLst.Add(new Mesa.Data() {type=1, m_points=points });
            }
            m_MesaNode.Add(mesa);
        }
        public override void AjustLineAndPoint()
        {
            foreach (Group group in base.GetGroups())
            {
                List<Mesa> objLst = m_MesaNode.Where(o => group.GetAllEntityIds().Contains(o.id)).OrderBy(o=>Area.GetArea(o.m_PointLst[0].m_points)).ToList();
                if (objLst.Count>1)
                {
                    //只保留第一个
                    for (int i = 1; i < objLst.Count; i++)
                    {
                        objLst[0].m_PointLst.Add(new Mesa.Data() { type=2,m_points=objLst[i].m_PointLst[0].m_points});
                        m_MesaNode.Remove(objLst[i]);
                    }
                }
            }
            
            //位置矫正
            Point center = m_house.Item<Points>().m_Center;
            m_MesaNode.ForEach(o=> { o.m_PointLst.ForEach(t => t.m_points.ForEach(x => { x.Offset(center); }));});
        }
        public override IEnumerable<XElement> ToXml()
        {
            int idx = 0;
            foreach (Mesa ms in m_MesaNode)
                yield return new XElement("_" + idx++, ms.ToXml());
        }
    }
}
